﻿using Opc.Ua;
using System;
using System.Linq;

namespace SD.OPC.UaProvider.Extensions
{
    /// <summary>
    /// List of static utility methods
    /// </summary>
    internal static class ClientUtils
    {
        // TODO I didn't write these methods. I should rewrite it once I understand whtat it does, beacuse it looks crazy

        public static EndpointDescription SelectEndpoint(Uri discoveryUrl, bool useSecurity)
        {
            EndpointConfiguration configuration = EndpointConfiguration.Create();
            configuration.OperationTimeout = 5000;
            EndpointDescription endpointDescription1 = null;
            using (DiscoveryClient discoveryClient = DiscoveryClient.Create(discoveryUrl, configuration))
            {
                EndpointDescriptionCollection endpoints = discoveryClient.GetEndpoints(null);
                foreach (EndpointDescription endpointDescription2 in endpoints.Where(endpointDescription2 => endpointDescription2.EndpointUrl.StartsWith(discoveryUrl.Scheme)))
                {
                    if (useSecurity)
                    {
                        if (endpointDescription2.SecurityMode == MessageSecurityMode.None)
                        {
                            continue;
                        }
                    }
                    else if (endpointDescription2.SecurityMode != MessageSecurityMode.None)
                    {
                        continue;
                    }

                    if (endpointDescription1 == null)
                    {
                        endpointDescription1 = endpointDescription2;
                    }
                    if (endpointDescription2.SecurityLevel > endpointDescription1.SecurityLevel)
                    {
                        endpointDescription1 = endpointDescription2;
                    }
                }
                if (endpointDescription1 == null)
                {
                    if (endpoints.Count > 0)
                    {
                        endpointDescription1 = endpoints[0];
                    }
                }
            }

            Uri uri = Utils.ParseUri(endpointDescription1.EndpointUrl);
            if (uri != null && uri.Scheme == discoveryUrl.Scheme)
            {
                endpointDescription1.EndpointUrl = new UriBuilder(uri)
                {
                    Host = discoveryUrl.DnsSafeHost,
                    Port = discoveryUrl.Port
                }.ToString();
            }

            return endpointDescription1;
        }
    }
}
